package com.mate.cloud.monitor.support;

import de.codecentric.boot.admin.server.domain.entities.Instance;
import de.codecentric.boot.admin.server.domain.entities.InstanceRepository;
import de.codecentric.boot.admin.server.domain.events.InstanceEvent;
import de.codecentric.boot.admin.server.domain.events.InstanceStatusChangedEvent;
import de.codecentric.boot.admin.server.notify.AbstractStatusChangeNotifier;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

/**
 * admin-server的通知扩展
 * 继承 AbstractStatusChangeNotifier 类，实现了 doNotify 方法，
 *  * 当应用状态改变的时候会回调 doNotify 方法。
 * @author cong zhi
 * @email  448341911@qq.com
 * @createDate   2023/3/10 17:01
 * @version: v1.0
 */
@Slf4j
@Component
public class CustomNotifierConfig extends AbstractStatusChangeNotifier {

    public CustomNotifierConfig(InstanceRepository repository) {
        super(repository);
    }

    /**
     * 执行通知
     * 通过查看源码发现，只有在 admin 中注册过了的实例，才会触发调用这个方法，所以新注册的服务进不了这里
     *
     * @param event    事件
     * @param instance 实例
     * @return
     */
    @Override
    protected Mono<Void> doNotify(InstanceEvent event, Instance instance) {
        return Mono.fromRunnable(()->{
            if (event instanceof InstanceStatusChangedEvent) {
                log.info("Instance {} ({}) is {}", instance.getRegistration().getName(), event.getInstance(),
                        ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus());
                String status = ((InstanceStatusChangedEvent) event).getStatusInfo().getStatus();

                switch (status) {
                    case "DOWN":
                        // 服务掉线，心跳丢失
                        log.info(">>>>>>>>>> {} 服务的实例 {} 掉线(心跳丢失)，服务地址：{}", instance.getRegistration().getName(),
                                instance.getId(), instance.getRegistration().getServiceUrl());
                        break;
                    case "OFFLINE":
                        // 服务离线了
                        log.info(">>>>>>>>>> {} 服务的实例 {} 离线(服务宕机或者停止)，服务地址：{}", instance.getRegistration().getName(),
                                instance.getId(), instance.getRegistration().getServiceUrl());
                        break;
                    case "UP":
                        // 服务重新上线
                        log.info(">>>>>>>>>> {} 服务的实例 {} 重新上线了，服务地址：{}", instance.getRegistration().getName(),
                                instance.getId(), instance.getRegistration().getServiceUrl());
                        break;
                    case "UNKNOWN":
                        // 未知异常
                        log.info(">>>>>>>>>> {} 服务的实例 {} 出现未知异常，服务地址：{}", instance.getRegistration().getName(),
                                instance.getId(), instance.getRegistration().getServiceUrl());
                        break;
                    default:
                        // 其他情况
                        log.info(">>>>>>>>>> {} 服务的实例 {} 出现未知状况，服务地址：{}", instance.getRegistration().getName(),
                                instance.getId(), instance.getRegistration().getServiceUrl());
                        break;
                }
            }
        });
    }
}
